# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File       : base_parse.py
# Time       ：2023/1/10 22:39
# Author     ：Y-aong
# version    ：python 3.7
# Description：
    模型基类
    base model
"""
from flask_sqlalchemy import SQLAlchemy as _SQLAlchemy
from sqlalchemy import Column, SmallInteger, func
from sqlalchemy.pool import QueuePool
from contextlib import contextmanager

from conf.config import FlaskConfig
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session


def get_session():
    db_uri = FlaskConfig.SQLALCHEMY_DATABASE_URI
    engine = create_engine(
        url=db_uri,
        poolclass=QueuePool,
        pool_recycle=3600,
        pool_pre_ping=True,
        pool_size=10,
        max_overflow=20,
        pool_timeout=30,
    )
    session_factory = sessionmaker(bind=engine, expire_on_commit=False)
    return scoped_session(session_factory)()


@contextmanager
def session_scope():
    """Provide a transactional scope around a series of operations."""
    session = get_session()
    try:
        yield session
        session.commit()
    except Exception as e:
        session.rollback()
        raise e
    finally:
        session.close()


class SQLAlchemy(_SQLAlchemy):
    @contextmanager
    def auto_commit(self):
        try:
            yield
            self.session.commit()
        except Exception as e:
            db.session.rollback()
            raise e


db = SQLAlchemy()


class Base(db.Model):
    __abstract__ = True
    id = Column(db.Integer, primary_key=True, autoincrement=True)
    active = Column(SmallInteger, default=1)
    insert_time = db.Column(db.DateTime, default=func.now(), comment='插入时间')
    update_time = db.Column(db.DateTime, onupdate=func.now(), comment='更新时间')
    creator_name = db.Column(db.String(64), comment='创建者姓名')
    creator_id = db.Column(db.Integer, comment='创建者ID')
    updater_name = db.Column(db.String(64), comment='更新者姓名')
    updater_id = db.Column(db.Integer, comment='更新者姓名')

    def set_attrs(self, attrs_dict):
        for key, value in attrs_dict.items():
            if hasattr(self, key) and key != 'id':
                setattr(self, key, value)

    def delete(self):
        self.active = 0
